#include "jsapi.h"
#include "js-engine.h"
#include "desktopClasses.h"
#include "basicElementClass.h"
#include "mainview-parser.h"
#include <string.h>

static JSBool listbox_new(JSContext *cx, JSObject *obj, uintN argc, jsval *args, jsval *rval);
static	JSBool listbox_clearSelection(JSContext *cx, JSObject *obj, uintN argc, jsval *args, jsval *rval);
void desktop_element_cancel_other_items(desktop_element *listbox, desktop_element *selectedItem);

static JSFunctionSpec listbox_methods[] = {
    {"clearSelection", listbox_clearSelection, 0, 0, 0},
    {NULL, NULL, 0, 0, 0}
};

JSClass listboxClass =
    { "listbox", JSCLASS_HAS_PRIVATE,
      JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
      JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
      JSCLASS_NO_OPTIONAL_MEMBERS
    };

struct property_parser listbox_parser[] = {
    /* from basicElement */
    {"cursor", set_property_string_value},
    {"dropTarget", set_property_boolean_value},
    {"enabled", set_property_boolean_value},
    {"height", set_property_integer_value},
    {"hitTest", set_property_string_value},
    {"mask", set_property_string_value},
    {"name", set_property_string_value},
    {"offsetHeight", set_property_integer_value},
    {"offsetWidth", set_property_integer_value},
    {"offsetX", set_property_integer_value},
    {"offsetY", set_property_integer_value},
    {"opacity", set_property_integer_value},
    {"pinX", set_property_integer_value},
    {"pinY", set_property_integer_value},
    {"rotation", set_property_float_value},
    {"tagName", set_property_string_value},
    {"tooltip", set_property_string_value},
    {"width", set_property_integer_value},
    {"visible", set_property_boolean_value},
    {"x", set_property_integer_value},
    {"y", set_property_integer_value},
		
    {"autoscroll", set_property_boolean_value},
    {"background", set_property_string_value},
    {"itemHeight", set_property_integer_value},
    {"itemOverColor", set_property_string_value},
    {"itemSelectedColor", set_property_string_value},
    {"itemSeparator", set_property_boolean_value},
    {"itemWidth", set_property_integer_value},
    {"multiSelect", set_property_boolean_value},
    {"selectedIndex", set_property_integer_value},
    {"selectedItem", set_property_stub},
    {NULL, NULL},
};

static JSBool listbox_new(JSContext *cx, JSObject *obj, uintN argc, jsval *args, jsval *rval)
{
    return JS_TRUE;
}

static	JSBool listbox_clearSelection(JSContext *cx, JSObject *obj, uintN argc, jsval *args, jsval *rval)
{
    desktop_element *listbox = JS_GetPrivate(cx, obj);
    desktop_element_cancel_other_items(listbox, NULL);
    return JS_TRUE;
}

JSObject *listboxClass_init(js_engine *engine, JSObject *parent)
{
    JSObject *proto = NULL;
    proto = JS_InitClass(engine->cx, engine->glob, parent,
			 &listboxClass, listbox_new,
			 0,NULL,NULL,NULL,NULL);
    g_return_val_if_fail(proto, FALSE);
    g_return_val_if_fail(JS_DefineFunctions(engine->cx, proto, listbox_methods), FALSE);
    return proto;
}

void desktop_element_cancel_other_items(desktop_element *listbox, desktop_element *selectedItem)
{
    int i;
    for(i = 0; i < g_list_length(listbox->children); i++){
	desktop_element *child = g_list_nth_data(listbox->children, i);
	if(child != selectedItem){
	    jsval selected = JSVAL_FALSE;
	    JS_SetProperty(child->engine->cx, child->jsobj, 
			   "selected", &selected);
	    gtk_widget_queue_draw(child->view);
	}
    }
}

void desktop_element_set_view_listbox(js_engine *engine, desktop_element *element)
{
    GtkAdjustment *ad = (GtkAdjustment *)gtk_adjustment_new(0,0,100, 1,5,5);
    GtkWidget *viewport = gtk_viewport_new(NULL, ad);
    GtkWidget *fixed = gtk_fixed_new();
    jsval background;

    element->view = gtk_scrolled_window_new(NULL, ad);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(element->view), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
    gtk_container_add(GTK_CONTAINER(element->view), viewport);
    gtk_container_add(GTK_CONTAINER(viewport), fixed);
    JS_GetProperty(element->engine->cx, element->jsobj, "background", &background);

    if(JSVAL_IS_STRING(background)){
	gchar *color = g_strdup(JS_GetStringBytes(JSVAL_TO_STRING(background)));
	GdkColor bgColor;
	if(strlen(color) == 7 && color[0] == '#'){
	    bgColor.blue = g_ascii_strtoull(&color[5], NULL, 16)*255;
	    color[5] = '\0';
	    bgColor.green = g_ascii_strtoull(&color[3], NULL, 16)*255;
	    color[3] = '\0';
	    bgColor.red = g_ascii_strtoull(&color[1], NULL, 16)*255;
	}
	g_free(color);
	gtk_widget_modify_bg (viewport, GTK_STATE_NORMAL, &bgColor);
	gtk_widget_modify_bg (fixed, GTK_STATE_NORMAL, &bgColor);
    }
    set_element_event_cb(element);
}
